package com.pzhu.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pzhu.common.constant.Constant;
import com.pzhu.common.constant.ErrorCode;
import com.pzhu.model.entity.Role;
import com.pzhu.model.entity.User;
import com.pzhu.model.entity.UserRole;
import com.pzhu.model.help.PageBean;
import com.pzhu.model.help.ResponseResult;
import com.pzhu.model.vo.UserInfoVo;
import com.pzhu.service.MenuService;
import com.pzhu.service.RoleService;
import com.pzhu.service.UserRoleService;
import com.pzhu.service.UserService;
import com.pzhu.utils.BeanCopyUtils;
import com.pzhu.utils.DateUtil;
import com.pzhu.utils.RedisUtil;
import com.pzhu.utils.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.security.Principal;
import java.util.*;

/**
 * @Author : zqh
 * @Date : 2023/11/26 0026 下午 4:48
 * @Version: 1.0
 */
@RestController
@Api(tags = "用户控制器")
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Value("${avatarImagesFilePath}")
    private String avatarImagesFilePath;


    @ApiOperation("查询用户基本信息")
    @GetMapping("/info")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResponseResult userInfo(Principal principal){
        Map<String,Object> resultMap=new HashMap<>();
        User sysUser = userService.getByUserName(principal.getName());
        UserInfoVo currentUser = BeanCopyUtils.copyBean(sysUser, UserInfoVo.class);
        resultMap.put("currentUser",currentUser);
        return ResponseResult.ok(resultMap);
    }

    /**
     * 验证用户名
     * @param user
     * @return
     */
    @ApiOperation("验证用户名")
    @PostMapping("/checkUserName")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResponseResult checkUserName(@RequestBody User user){
        if(userService.getByUserName(user.getUsername())==null){
            return ResponseResult.ok();
        }else{
            return ResponseResult.error(ErrorCode.NOT_EXIT_NAME);
        }
    }

    /**
     * 分页查询用户信息
     * @param pageBean
     * @return
     */
    @ApiOperation("分页查询用户信息")
    @PostMapping("/list")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResponseResult list(@RequestBody PageBean pageBean){
        System.out.println("pageBean:"+pageBean);
        String query=pageBean.getQuery().trim();
        Page<User> pageResult = userService.page(
                new Page<>(pageBean.getPageNum(),pageBean.getPageSize()),
                new QueryWrapper<User>().eq("role",0).like(StringUtil.isNotEmpty(query), "username", query));
        List<User> userList = pageResult.getRecords();


        for(User user:userList){
            // 获取角色
            List<Role> roleList = roleService.list(new QueryWrapper<Role>().inSql("id", "select role_id from hs_user_role where user_id=" + user.getId()));
            // 设置角色
            user.setRoleList(roleList);
        }
        Map<String,Object> resultMap=new HashMap<>();
        resultMap.put("userList",userList);
        resultMap.put("total",pageResult.getTotal());
        return ResponseResult.ok(resultMap);
    }

    /**
     * 添加或者修改
     * @param user
     * @return
     */
    @ApiOperation("添加或修改用户")
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:user:add')"+"||"+"hasAuthority('system:user:edit')")
    public ResponseResult save(@RequestBody @Valid User user){
        if(user.getId()==null || user.getId()==-1){
            user.setCreateTime(new Date());
            user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
            userService.save(user);
        }else{
            user.setUpdateTime(new Date());
            userService.updateById(user);
        }
        return ResponseResult.ok();
    }

    /**
     * 修改密码
     * @param user
     * @return
     */
    @ApiOperation("修改用户密码")
    @PostMapping("/updateUserPwd")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResponseResult updateUserPwd(@RequestBody User user){
        User currentUser = userService.getById(user.getId());
        currentUser.setPassword(bCryptPasswordEncoder.encode(user.getNewPassword()));
        userService.updateById(currentUser);
        return ResponseResult.ok();
    }

    /**
     * 更新status状态
     * @param id
     * @param status
     * @return
     */
    @ApiOperation("更新用户状态")
    @GetMapping("/updateStatus/{id}/status/{status}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",value = "用户ID",required = true),
            @ApiImplicitParam(name = "status",value = "用户状态",required = true),
    })
    public ResponseResult updateStatus(@PathVariable(value = "id")Integer id, @PathVariable(value = "status")String status){
        User user = userService.getById(id);
        user.setStatus(status);
        userService.saveOrUpdate(user);
        redisUtil.removeByPrex(Constant.AUTHORITY_KEY);
        return ResponseResult.ok();
    }

    /**
     * 根据id查询
     * @param id
     * @return
     */
    @ApiOperation("根据用户Id查询")
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('system:user:query')")
    @ApiImplicitParam(name = "id",value = "用户ID",required = true)
    public ResponseResult findById(@PathVariable(value = "id")Integer id){
        User user = userService.getById(id);
        Map<String,Object> map=new HashMap<>();
        map.put("sysUser",user);
        return ResponseResult.ok(map);
    }

    /**
     * 重置密码
     * @param id
     * @return
     */
    @ApiOperation("重置用户密码")
    @GetMapping("/resetPassword/{id}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    @ApiImplicitParam(name = "id",value = "用户ID",required = true)
    public ResponseResult resetPassword(@PathVariable(value = "id")Integer id){
        User sysUser = userService.getById(id);
        sysUser.setPassword(bCryptPasswordEncoder.encode(Constant.DEFAULT_PASSWORD));
        sysUser.setUpdateTime(new Date());
        userService.updateById(sysUser);
        return ResponseResult.ok();
    }

    /**
     * 修改用户头像
     * @param user
     * @return
     */
    @ApiOperation("修改用户头像")
    @RequestMapping("/updateAvatar")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResponseResult updateAvatar(@RequestBody User user){
        User currentUser = userService.getById(user.getId());
        currentUser.setAvatar(user.getAvatar());
        userService.updateById(currentUser);
        return ResponseResult.ok();
    }

    /**
     * 上传用户头像图片
     * @param file
     * @return
     * @throws Exception
     */
    @ApiOperation("上传用户头像")
    @RequestMapping("/uploadImage")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Map<String,Object> uploadImage(MultipartFile file)throws Exception{
        Map<String,Object> resultMap=new HashMap<>();
        if(!file.isEmpty()){
            // 获取文件名
            String originalFilename = file.getOriginalFilename();
            String suffixName=originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFileName= DateUtil.getCurrentDateStr()+suffixName;
            FileUtils.copyInputStreamToFile(file.getInputStream(),new File(avatarImagesFilePath+newFileName));
            resultMap.put("code",0);
            resultMap.put("msg","上传成功");
            Map<String,Object> dataMap=new HashMap<>();
            dataMap.put("title",newFileName);
            dataMap.put("src","image/userAvatar/"+newFileName);
            resultMap.put("data",dataMap);
        }
        return resultMap;
    }

    /**
     * 删除
     * @param ids
     * @return
     */
    @Transactional
    @ApiOperation("批量删除用户")
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('system:user:delete')")
    public ResponseResult delete(@RequestBody Long[] ids){
        userService.removeByIds(Arrays.asList(ids));
        userRoleService.remove(new LambdaQueryWrapper<UserRole>().in(UserRole::getUserId,ids));
        redisUtil.removeByPrex(Constant.AUTHORITY_KEY);
        return ResponseResult.ok();
    }

    /**
     * 用户角色授权
     * @param userId
     * @param roleIds
     * @return
     */
    @Transactional
    @ApiOperation("用户角色绑定")
    @PostMapping("/grantRole/{userId}")
    @PreAuthorize("hasAuthority('system:user:role')")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true),
            @ApiImplicitParam(name = "roleIds", value = "角色的Id集合")
    })
    public ResponseResult grantRole(@PathVariable("userId") Long userId, @RequestBody Long[] roleIds){
        List<UserRole> userRoleList=new ArrayList<>();
        Arrays.stream(roleIds).forEach(r -> {
            UserRole userRole = new UserRole();
            userRole.setRoleId(r);
            userRole.setUserId(userId);
            userRoleList.add(userRole);
        });
        userRoleService.remove(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId,userId));
        userRoleService.saveBatch(userRoleList);
        redisUtil.removeByPrex(Constant.AUTHORITY_KEY);
        return ResponseResult.ok();
    }

}
